class SpringChain extends egret.Sprite {
    private ball0: Ball
    private ball1: Ball
    private ball2: Ball
    private spring: number = 0.03
    private targetX: number = 0
    private targetY: number = 0
    private friction: number = 0.95
    private gravity: number = 2

    public constructor() {
        super()
        this.once(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this)
    }

    private onAddToStage(event: egret.Event) {
        this.targetX = this.stage.stageWidth / 2
        this.targetY = this.stage.stageHeight / 2
        this.ball0 = new Ball(20)
        this.addChild(this.ball0)
        this.ball1 = new Ball(20)
        this.addChild(this.ball1)
        this.ball2 = new Ball(20)
        this.addChild(this.ball2)
        this.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.trackTouch, this)
        this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this)
    }

    private onEnterFrame(event: egret.Event) {
        this.moveBall(this.ball0, this.targetX, this.targetY)
        this.moveBall(this.ball1, this.ball0.x, this.ball0.y)
        this.moveBall(this.ball2, this.ball1.x, this.ball1.y)
       
        this.graphics.clear()
        this.graphics.lineStyle(1)
        this.graphics.moveTo(this.targetX, this.targetY)
        this.graphics.lineTo(this.ball0.x, this.ball0.y)
        this.graphics.lineTo(this.ball1.x, this.ball1.y)
        this.graphics.lineTo(this.ball2.x, this.ball2.y)
    }

    private moveBall(ball:Ball, targetX:number, targetY:number) {
        let dx = targetX - ball.x
        let dy = targetY - ball.y
        let ax = dx * this.spring
        let ay = dy * this.spring
        ball.vx += ax
        ball.vy += ay
        ball.vy += this.gravity
        ball.vx *= this.friction
        ball.vy *= this.friction
        ball.x += ball.vx
        ball.y += ball.vy
    }

    private trackTouch(evt:egret.TouchEvent) {
        this.targetX = evt.stageX
        this.targetY = evt.stageY
    }
}